package com.ybkj.daijia.api.member.v3;

import com.alibaba.fastjson.JSONObject;
import com.ybkj.daijia.serverUtils.HttpClientUtil;
import com.ybkj.daijia.serverUtils.QRCodeUtil;
import com.ybkj.daijia.ServiceSetting;
import com.ybkj.daijia.serverUtils.ServiceUtil;
import com.ybkj.daijia.Setting;
import com.ybkj.daijia.serverUtils.SettingUtils;
import com.ybkj.daijia.api.member.Error;
import com.ybkj.daijia.api.member.ErrorConstant;
import com.ybkj.daijia.api.member.SecurityUtils;
import com.ybkj.daijia.api.member.transport.ResultTransport;
import com.ybkj.daijia.common.HtmlHelper;
import com.ybkj.daijia.common.RandomString;
import com.ybkj.daijia.common.Result;
import com.ybkj.daijia.page.Page;
import com.ybkj.daijia.server.Config;
import com.ybkj.daijia.server.event.model.ActivityCheckEvent;
import com.ybkj.daijia.server.event.model.MemberRebateEvent;
import com.ybkj.daijia.server.event.model.OrderCreateEvent;
import com.ybkj.daijia.server.event.model.OrderNewRushEvent;
import com.ybkj.daijia.server.event.model.OrderRecordEvent;
import com.ybkj.daijia.server.mc.Passenger;
import com.ybkj.daijia.server.model.Advert;
import com.ybkj.daijia.server.model.AppVersion;
import com.ybkj.daijia.server.model.Brand;
import com.ybkj.daijia.server.model.Car;
import com.ybkj.daijia.server.model.Company;
import com.ybkj.daijia.server.model.Driver;
import com.ybkj.daijia.server.model.MemberRebate;
import com.ybkj.daijia.server.model.Order;
import com.ybkj.daijia.server.model.Order.OrderCarType;
import com.ybkj.daijia.server.model.Order.OrderCarTypeDetail;
import com.ybkj.daijia.server.model.OrderStatus;
import com.ybkj.daijia.server.model.PhoneSmsRecord;
import com.ybkj.daijia.server.model.Receipt;
import com.ybkj.daijia.server.model.ShareRecord;
import com.ybkj.daijia.server.model.ShareRecord.SharePlatform;
import com.ybkj.daijia.server.model.SmsTemplet;
import com.ybkj.daijia.server.model.SmsTemplet.SmsType;
import com.ybkj.daijia.server.model.UsuallyDriver;
import com.ybkj.daijia.server.reactor.ReactorVo;
import com.ybkj.daijia.server.sales.Activity.ActivityEvent;
import com.ybkj.daijia.server.service.AdvertService;
import com.ybkj.daijia.server.service.AppVersionService;
import com.ybkj.daijia.server.service.AreaService;
import com.ybkj.daijia.server.service.BrandService;
import com.ybkj.daijia.server.service.CarService;
import com.ybkj.daijia.server.service.CarTypeService;
import com.ybkj.daijia.server.service.CompanyService;
import com.ybkj.daijia.server.service.DriverService;
import com.ybkj.daijia.server.service.MemberAccountService;
import com.ybkj.daijia.server.service.MemberService;
import com.ybkj.daijia.server.service.OrderService;
import com.ybkj.daijia.server.service.OrderStatusService;
import com.ybkj.daijia.server.service.PhoneSmsRecordService;
import com.ybkj.daijia.server.service.RateService;
import com.ybkj.daijia.server.service.ReceiptService;
import com.ybkj.daijia.server.service.SmsService;
import com.ybkj.daijia.server.service.UsuallyDriverService;
import com.ybkj.daijia.server.service.ZhuancheService;
import com.ybkj.daijia.server.zhuan.CarType;
import freemarker.cache.FileTemplateLoader;
import freemarker.template.Configuration;
import freemarker.template.Template;
import freemarker.template.TemplateException;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.StringWriter;
import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.Date;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import java.util.Random;
import javax.servlet.http.HttpServletRequest;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.event.ApplicationEventMulticaster;
import org.springframework.core.io.support.PropertiesLoaderUtils;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.util.CollectionUtils;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.util.WebUtils;

/**
 * @author bo
 */
@Controller("memberProcessV3Controller")
@RequestMapping(value = "member/api/rest/v3")
public class ProcessController {

    private static final Logger logger = LoggerFactory.getLogger(ProcessController.class);

    @Autowired
    private MemberService memberService;
    @Autowired
    private CarService carService;
    @Autowired
    private AppVersionService appVersionService;
    @Autowired
    private MemberAccountService memberAccountService;
    @Autowired
    private PhoneSmsRecordService phoneSmsRecordService;
    @Autowired
    private DriverService driverService;
    @Autowired
    private OrderService orderService;
    @Autowired
    private CompanyService companyService;
    @Autowired
    private RateService rateService;
    @Autowired
    private UsuallyDriverService usuallyDriverService;
    @Autowired
    private AreaService areaService;
    @Autowired
    private OrderStatusService orderStatusService;
    @Autowired
    private SettingUtils settingUtils;
    @Autowired
    private ApplicationEventMulticaster applicationEventMulticaster;
    @Autowired
    private AdvertService advertService;
    @Autowired
    private ReceiptService receiptService;
    @Autowired
    private BrandService brandService;
    @Autowired
    private CarTypeService carTypeService;
    @Autowired
    private ZhuancheService zhuancheService;
    @Autowired
    private SmsService smsService;

    /**
     * 获取附近司机
     *
     * @param longitude 经度
     * @param latitude  纬度
     * @param appKey
     * @param token     token令牌
     * @param timestamp 时间戳
     * @return
     */
    @RequestMapping(value = "queryNearDrivers", method = RequestMethod.POST)
    public @ResponseBody
    ResultTransport queryNearDrivers(Double longitude, Double latitude,
        Integer type, String appKey, String token, String timestamp) {

        logger.error("recv longitude:{},latitude:{},type:{},appKey:{},token:{},timestamp:{}",
            longitude, latitude, type, appKey, token, timestamp);

        if (null == longitude || null == latitude || SecurityUtils
            .isBlank(appKey, token, timestamp)) {
            return ResultTransport.getErrorBy(ErrorConstant.PARAM_ERROR);
        }

        // if(!StringUtils.isNumeric(timestamp) ||
        // !SecurityUtils.checkTimestamp(Long.parseLong(timestamp))) {
        // return ResultTransport.getErrorBy(ErrorConstant.TIMESTAMP_ERROR);
        // }

        List<String> params = new LinkedList<String>();
        params.add(String.valueOf(longitude));
        params.add(String.valueOf(latitude));
        params.add(timestamp);
        params.add(appKey);

        // if (!SecurityUtils.checkToken(params, token)) {
        // return ResultTransport.getErrorBy(ErrorConstant.TOKEN_ERROR);
        // }

        try {

            List<Driver> drivers = driverService.queryNearDrivers(longitude, latitude,
                Driver.DriverJobType.daijia.toString());

            Setting setting = settingUtils.get();

            List<Map<String, Object>> mapList = new ArrayList<Map<String, Object>>();
            if (org.apache.commons.collections.CollectionUtils.isNotEmpty(drivers)) {
                for (Driver driver : drivers) {
                    Map<String, Object> map = new HashMap<String, Object>();
                    map.put("driverId", driver.getId());
                    map.put("driverName", driver.getName());
                    map.put("driverUserName", driver.getUsername());
                    map.put("driverHead",
                        setting.getWebUrl() + "/upload/driver/" + driver.getPhoto());
                    map.put("driverStar", driver.getStarLevel());
                    map.put("driverTimes", driver.getDriveTimes());
                    map.put("driverJialing", driver.getjialing());
                    map.put("driverDistance", driver.getDistanceStr());
                    map.put("driverMeter", driver.getDistance() * 1000);
                    if (driver.getStatus().equals(Driver.DRIVER_ONLINE)) {
                        map.put("driverStatus", 0);
                    } else {
                        map.put("driverStatus", 1);
                    }
                    map.put("driverLng", driver.getLongitude());
                    map.put("driverLat", driver.getLatitude());

                    // car
                    if (null != driver.getCarId()) {
                        Car car = carService.findById(driver.getCarId());
                        if (null != car) {
                            map.put("carPhoto",
                                setting.getWebUrl() + "/upload/driverCar/" + car.getPicture());
                            map.put("carName", car.getName());
                        }
                    }
                    mapList.add(map);
                }
            }

            ResultTransport instance = ResultTransport.getErrorBy(ErrorConstant.SUCCESS);
            instance.setData(mapList);

            return instance;

        } catch (Exception e) {
            logger.error("api v3 queryNearDrivers error: {}", e);
            return ResultTransport.getErrorBy(ErrorConstant.SERVER_ERROR);
        }

    }

    /**
     * 自主预约
     *
     * @param longitude
     * @param latitude
     * @param phone
     * @param driverId
     * @param acKey
     * @param type
     * @param couponId
     * @param appKey
     * @param token
     * @param timestamp
     * @return
     */
    @RequestMapping(value = "customerOrder", method = RequestMethod.POST)
    public @ResponseBody
    ResultTransport customerOrder(Double longitude, Double latitude,
        String phone, Long driverId, String acKey, Integer type, Long couponId, String appKey,
        String token, String timestamp) {

        logger
            .debug(
                "recv phone:{},driverId:{},longitude:{},latitude:{},type:{},couponId{},appKey:{},token:{},timestamp:{}",
                phone, driverId, longitude, latitude, type, couponId, appKey, token, timestamp);

        if (StringUtils.isBlank(phone) || null == driverId || null == longitude || null == latitude
            || SecurityUtils.isBlank(appKey, token, timestamp)) {
            return ResultTransport.getErrorBy(ErrorConstant.PARAM_ERROR);
        }

        // if(!StringUtils.isNumeric(timestamp) ||
        // !SecurityUtils.checkTimestamp(Long.parseLong(timestamp))) {
        // return ResultTransport.getErrorBy(ErrorConstant.TIMESTAMP_ERROR);
        // }

        List<String> params = new LinkedList<String>();
        params.add(String.valueOf(phone));
        params.add(String.valueOf(driverId));
        params.add(String.valueOf(longitude));
        params.add(String.valueOf(latitude));
        params.add(timestamp);
        params.add(appKey);

        if (!SecurityUtils.checkToken(params, token)) {
            return ResultTransport.getErrorBy(ErrorConstant.TOKEN_ERROR);
        }

        try {

            Driver driver = driverService.findOne(driverId);
            if (null == driver) {
                return ResultTransport.getErrorBy(ErrorConstant.DRIVER_NOT_EXISTS_ERROR);
            }

            Passenger passenger = memberService.findOnePassengerByPhone(phone);
            if (null == passenger) {
                return ResultTransport.getErrorBy(ErrorConstant.MEMBER_NOT_EXISTS_ERROR);
            }

            Order order = new Order();

            try {
                order.setFromPlace(HttpClientUtil.getPlaceByLngAndLat(longitude, latitude));
            } catch (Exception e) {
                logger.error(e.getMessage());
            }

            order.setClientLongitude(longitude);
            order.setClientLatitude(latitude);
            order.setClientName(passenger.getName());
            order.setClientPhone(phone);
            order.setFromSource("APP下单");
            order.setServerTime(new Date());
            order.setStatus(Order.ORDER_STATUS_NEW);
            order.setOrderCarType(OrderCarType.daijia);
            order.setOrderCarTypeDetail(OrderCarTypeDetail.jhdj);
            order.setCouponId(couponId);

            orderService.customerOrder(order, driver, passenger, acKey);

            ResultTransport instance = ResultTransport.getErrorBy(ErrorConstant.SUCCESS); // 下单成功
            instance.setData(order);

            return instance;

        } catch (Exception e) {
            logger.error("api v3 member customerOrder error: {}", e);
            return ResultTransport.getErrorBy(ErrorConstant.SERVER_ERROR);
        }

    }

    /**
     * 一键下单
     *
     * @param longitude
     * @param latitude
     * @param serverTimeStamp
     * @param fromPlace
     * @param driverNum
     * @param phone
     * @param userPhone
     * @param acKey
     * @param type
     * @param couponId
     * @param appKey
     * @param token
     * @param timestamp
     * @return
     */
    @RequestMapping(value = "orderAppointment", method = RequestMethod.POST)
    public @ResponseBody
    ResultTransport orderAppointment(Double longitude, Double latitude,
        Long serverTimeStamp, String fromPlace, Integer driverNum, String phone, String userPhone,
        String acKey, Integer type, Long couponId, String appKey, String token, String timestamp) {

        logger
            .debug(
                "recv longitude:{},latitude:{},serverTimeStamp:{},fromPlace:{},driverNum:{},phone:{},userPhone:{},acKey:{},type:{},couponId:{},appKey:{},token:{},timestamp:{}",
                longitude, latitude, serverTimeStamp, fromPlace, driverNum, phone, userPhone, acKey,
                type, couponId, appKey, token, timestamp);

        if (null == longitude || null == latitude || null == serverTimeStamp
            || StringUtils.isBlank(fromPlace) || null == driverNum || StringUtils.isBlank(phone)
            || StringUtils.isBlank(userPhone) || SecurityUtils.isBlank(appKey, token, timestamp)) {
            return ResultTransport.getErrorBy(ErrorConstant.PARAM_ERROR);
        }

        // if(!StringUtils.isNumeric(timestamp) ||
        // !SecurityUtils.checkTimestamp(Long.parseLong(timestamp))) {
        // return ResultTransport.getErrorBy(ErrorConstant.TIMESTAMP_ERROR);
        // }

        List<String> params = new LinkedList<String>();
        params.add(String.valueOf(longitude));
        params.add(String.valueOf(latitude));
        params.add(String.valueOf(serverTimeStamp));
        params.add(fromPlace);
        params.add(String.valueOf(driverNum));
        params.add(phone);
        params.add(userPhone);
        params.add(timestamp);
        params.add(appKey);

        if (!SecurityUtils.checkToken(params, token)) {
            return ResultTransport.getErrorBy(ErrorConstant.TOKEN_ERROR);
        }

        try {

            Order order = new Order();
            order.setClientLongitude(longitude);
            order.setClientLatitude(latitude);
            order.setFromPlace(fromPlace);

            Passenger passenger = memberService.findOnePassengerByPhone(phone);

            order.setServerTime(new Date(serverTimeStamp));
            if (null != passenger) {
                order.setClientName(passenger.getName());
            } else {
                order.setClientName("先生/女士");
            }
            order.setClientPhone(phone);
            order.setUserPhone(userPhone);
            order.setFromSource("APP下单");
            order.setOrderCarType(OrderCarType.daijia);
            order.setOrderCarTypeDetail(OrderCarTypeDetail.jhdj);

            order.setCouponId(couponId);

            if (!phone.equals(userPhone)) {
                order.setMemo("客户帮助【" + userPhone + "】预约");
            }

            List<Order> newOrders = orderService
                .orderAppointment(order, driverNum, longitude, latitude,
                    acKey);

            for (Order order2 : newOrders) {

                OrderCreateEvent event = new OrderCreateEvent(order2);
                applicationEventMulticaster.multicastEvent(event);

                OrderRecordEvent orderRecordEvent = new OrderRecordEvent(order2);
                applicationEventMulticaster.multicastEvent(orderRecordEvent);
            }

            OrderNewRushEvent newRushEvent = new OrderNewRushEvent(newOrders);
            applicationEventMulticaster.multicastEvent(newRushEvent);

            if (null == passenger) {
                passenger = memberService.findOnePassengerByPhone(order.getClientPhone());
                ReactorVo rVo = new ReactorVo();
                rVo.setPassenger(passenger);
                rVo.setActivityEvent(ActivityEvent.newRegister);
                ActivityCheckEvent activityCheckEvent = new ActivityCheckEvent(rVo);
                applicationEventMulticaster.multicastEvent(activityCheckEvent);
            }

            ResultTransport instance = ResultTransport.getErrorBy(ErrorConstant.SUCCESS);
            instance.setData(newOrders.get(0));

            return instance;

        } catch (Exception e) {
            logger.error("api v3 orderAppointment error: {}", e);
            return ResultTransport.getErrorBy(ErrorConstant.SERVER_ERROR);
        }

    }

    /**
     * 历史订单
     *
     * @param phone
     * @param acKey
     * @param page
     * @param limit
     * @param appKey
     * @param token
     * @param timestamp
     * @return
     */
    @RequestMapping(value = "historyOrder", method = RequestMethod.POST)
    public @ResponseBody
    ResultTransport historyOrder(String phone, String acKey, Integer page,
        Integer limit, String appKey, String token, String timestamp) {

        logger.debug("recv phone:{},page:{},limit:{},appKey:{},token:{},timestamp:{}", phone, page,
            limit, appKey, token, timestamp);

        if (null == page || null == limit || StringUtils.isBlank(phone)
            || SecurityUtils.isBlank(appKey, token, timestamp)) {
            return ResultTransport.getErrorBy(ErrorConstant.PARAM_ERROR);
        }

        // if(!StringUtils.isNumeric(timestamp) ||
        // !SecurityUtils.checkTimestamp(Long.parseLong(timestamp))) {
        // return ResultTransport.getErrorBy(ErrorConstant.TIMESTAMP_ERROR);
        // }

        List<String> params = new LinkedList<String>();
        params.add(String.valueOf(phone));
        params.add(String.valueOf(page));
        params.add(String.valueOf(limit));
        params.add(timestamp);
        params.add(appKey);

        if (!SecurityUtils.checkToken(params, token)) {
            return ResultTransport.getErrorBy(ErrorConstant.TOKEN_ERROR);
        }

        try {

            Page<Map<String, Object>> pageOrders = orderService
                .historyOrderV3(phone, acKey, page, limit);

            ResultTransport instance = ResultTransport.getErrorBy(ErrorConstant.SUCCESS);
            instance.setData(pageOrders);

            return instance;

        } catch (Exception e) {
            logger.error("api v3 historyOrder error: {}", e);
            return ResultTransport.getErrorBy(ErrorConstant.SERVER_ERROR);
        }

    }

    /**
     * 当前订单(今日订单)
     *
     * @param appKey
     * @param token     token令牌
     * @param timestamp 时间戳
     * @return
     */
    @RequestMapping(value = "todayOrder", method = RequestMethod.POST)
    public @ResponseBody
    ResultTransport todayOrder(String phone, String acKey, String appKey,
        String token, String timestamp) {

        logger.debug("recv phone:{},appKey:{},token:{},timestamp:{}", phone, appKey, token,
            timestamp);

        if (StringUtils.isBlank(phone) || SecurityUtils.isBlank(appKey, token, timestamp)) {
            return ResultTransport.getErrorBy(ErrorConstant.PARAM_ERROR);
        }

        // if(!StringUtils.isNumeric(timestamp) ||
        // !SecurityUtils.checkTimestamp(Long.parseLong(timestamp))) {
        // return ResultTransport.getErrorBy(ErrorConstant.TIMESTAMP_ERROR);
        // }

        List<String> params = new LinkedList<String>();
        params.add(String.valueOf(phone));
        params.add(timestamp);
        params.add(appKey);

        if (!SecurityUtils.checkToken(params, token)) {
            return ResultTransport.getErrorBy(ErrorConstant.TOKEN_ERROR);
        }

        try {
            Setting setting = settingUtils.get();

            Page<Order> orders = orderService.todayOrder(phone, acKey, 0, 100);
            List<Order> orderlist = orders.getContent();

            List<Map<String, Object>> mapList = new ArrayList<Map<String, Object>>();
            if (org.apache.commons.collections.CollectionUtils.isNotEmpty(orderlist)) {
                for (Order order : orderlist) {

                    Map<String, Object> map = new HashMap<String, Object>();
                    map.put("orderId", order.getId());
                    map.put("orderNumber", order.getOrderNumber());
                    map.put("orderBookTime", order.getServerTime());
                    map.put("orderBookAddress", order.getFromPlace());
                    map.put("orderBookLat", order.getClientLatitude());
                    map.put("orderBookLng", order.getClientLongitude());
                    map.put("orderCarType", order.getOrderCarType());
                    map.put("orderStatus", order.getStatus());
                    if (null != order.getDriverId()) {
                        Driver driver = driverService.findOne(order.getDriverId());
                        if (null != driver) {
                            map.put("orderDriverId", driver.getId());
                            map.put("orderDriverAccount", driver.getUsername());
                            map.put("orderDriverName", driver.getName());
                            map.put("orderDriverHead",
                                setting.getWebUrl() + "/upload/driver/" + driver.getPhoto());
                            if (!setting.isAllowCallDriver()) {
                                Company company = companyService.findOne(order.getCompanyId());
                                map.put("orderDriverPhone", company.getTelephone());
                            } else {
                                map.put("orderDriverPh" + "one", driver.getPhone());
                            }
                            map.put("orderDriverLat", driver.getLatitude());
                            map.put("orderDriverLng", driver.getLongitude());
                            map.put("orderDriverAccept", order.getChufaTime());
                            map.put("orderDriverArrived", order.getDaokehuTime());
                            map.put("orderDriverStar", driver.getStarLevel());
                            map.put("orderDriverTimes", driver.getDriveTimes());
                            map.put("orderDriverJialing", driver.getjialing());
                        }
                    }
                    mapList.add(map);
                }
            }

            ResultTransport instance = ResultTransport.getErrorBy(ErrorConstant.SUCCESS);
            instance.setData(mapList);

            return instance;

        } catch (Exception e) {
            logger.error("api v3 todayOrder error: {}", e);
            return ResultTransport.getErrorBy(ErrorConstant.SERVER_ERROR);
        }

    }

    /**
     * 手动添加常用司机
     *
     * @param phone     手机号
     * @param appKey
     * @param token     token令牌
     * @param timestamp 时间戳
     * @return
     */
    @RequestMapping(value = "addUsuallyDriver", method = RequestMethod.POST)
    public synchronized @ResponseBody
    ResultTransport addUsuallyDriver(Long driverId, String phone,
        String appKey, String token, String timestamp) {

        logger.debug("recv driverId:{},phone:{},appKey:{},token:{},timestamp:{}", driverId, phone,
            appKey, token, timestamp);

        if (null == driverId || StringUtils.isBlank(phone)
            || SecurityUtils.isBlank(appKey, token, timestamp)) {
            return ResultTransport.getErrorBy(ErrorConstant.PARAM_ERROR);
        }

        // if(!StringUtils.isNumeric(timestamp) ||
        // !SecurityUtils.checkTimestamp(Long.parseLong(timestamp))) {
        // return ResultTransport.getErrorBy(ErrorConstant.TIMESTAMP_ERROR);
        // }

        List<String> params = new LinkedList<String>();
        params.add(String.valueOf(driverId));
        params.add(String.valueOf(phone));
        params.add(timestamp);
        params.add(appKey);

        if (!SecurityUtils.checkToken(params, token)) {
            return ResultTransport.getErrorBy(ErrorConstant.TOKEN_ERROR);
        }

        Passenger passenger = memberService.findOnePassengerByPhone(phone);
        if (null == passenger) {
            return ResultTransport.getErrorBy(ErrorConstant.MEMBER_NOT_EXISTS_ERROR);
        }

        Driver driver = driverService.findOne(driverId);
        if (null == driver) {
            return ResultTransport.getErrorBy(ErrorConstant.DRIVER_NOT_EXISTS_ERROR);
        }

        try {

            // 生成常用司机记录
            UsuallyDriver oldUsuallyDriver = usuallyDriverService
                .findByDriverAndMember(driverId, phone);
            if (null != oldUsuallyDriver) {
                return ResultTransport.getErrorBy(ErrorConstant.HASBEEN_USUALLY_DRIVER);
            } else {
                UsuallyDriver usuallyDriver = new UsuallyDriver();
                usuallyDriver.setDriverTime(1);
                usuallyDriver.setDriverId(driver.getId());
                usuallyDriver.setMemberId(passenger.getId());
                usuallyDriver.setPhone(phone);
                usuallyDriverService.insertRecord(usuallyDriver);
            }

            ResultTransport instance = ResultTransport.getErrorBy(ErrorConstant.SUCCESS);

            return instance;

        } catch (Exception e) {
            logger.error("api v3 addUsuallyDriver error: {}", e);
            return ResultTransport.getErrorBy(ErrorConstant.SERVER_ERROR);
        }

    }

    /**
     * 删除常用司机
     *
     * @param phone     手机号
     * @param appKey
     * @param token     token令牌
     * @param timestamp 时间戳
     * @return
     */
    @RequestMapping(value = "deleteUsuallyDriver", method = RequestMethod.POST)
    public synchronized @ResponseBody
    ResultTransport deleteUsuallyDriver(String phone,
        Long driverId, String appKey, String token, String timestamp) {

        logger.debug("recv phone:{},driverId:{},appKey:{},token:{},timestamp:{}", phone, driverId,
            appKey, token, timestamp);

        if (StringUtils.isBlank(phone) || null == driverId
            || SecurityUtils.isBlank(appKey, token, timestamp)) {
            return ResultTransport.getErrorBy(ErrorConstant.PARAM_ERROR);
        }

        // if(!StringUtils.isNumeric(timestamp) ||
        // !SecurityUtils.checkTimestamp(Long.parseLong(timestamp))) {
        // return ResultTransport.getErrorBy(ErrorConstant.TIMESTAMP_ERROR);
        // }

        List<String> params = new LinkedList<String>();
        params.add(String.valueOf(phone));
        params.add(String.valueOf(driverId));
        params.add(timestamp);
        params.add(appKey);

        if (!SecurityUtils.checkToken(params, token)) {
            return ResultTransport.getErrorBy(ErrorConstant.TOKEN_ERROR);
        }

        try {

            UsuallyDriver oldUsuallyDriver = usuallyDriverService
                .findByDriverAndMember(driverId, phone);
            if (null != oldUsuallyDriver) {
                usuallyDriverService.delete(oldUsuallyDriver);
            }

            ResultTransport instance = ResultTransport.getErrorBy(ErrorConstant.SUCCESS);

            return instance;

        } catch (Exception e) {
            logger.error("api v3 deleteUsuallyDriver error: {}", e);
            return ResultTransport.getErrorBy(ErrorConstant.SERVER_ERROR);
        }

    }

    /**
     * 获取用户常用司机
     *
     * @param phone     手机号
     * @param appKey
     * @param token     token令牌
     * @param timestamp 时间戳
     * @return
     */
    @RequestMapping(value = "getUsuallyDriver", method = RequestMethod.POST)
    public @ResponseBody
    ResultTransport getUsuallyDriver(String phone, Double longitude,
        Double latitude, String appKey, String token, String timestamp) {

        logger
            .debug("recv phone:{},longitude:{},latitude:{},appKey:{},token:{},timestamp:{}", phone,
                longitude, latitude, appKey, token, timestamp);

        if (StringUtils.isBlank(phone) || SecurityUtils.isBlank(appKey, token, timestamp)) {
            return ResultTransport.getErrorBy(ErrorConstant.PARAM_ERROR);
        }

        // if(!StringUtils.isNumeric(timestamp) ||
        // !SecurityUtils.checkTimestamp(Long.parseLong(timestamp))) {
        // return ResultTransport.getErrorBy(ErrorConstant.TIMESTAMP_ERROR);
        // }

        List<String> params = new LinkedList<String>();
        params.add(phone);
        params.add(String.valueOf(longitude));
        params.add(String.valueOf(latitude));
        params.add(timestamp);
        params.add(appKey);

        if (!SecurityUtils.checkToken(params, token)) {
            return ResultTransport.getErrorBy(ErrorConstant.TOKEN_ERROR);
        }

        Passenger passenger = memberService.findOnePassengerByPhone(phone);

        if (null == passenger) {
            return ResultTransport.getErrorBy(ErrorConstant.MEMBER_NOT_EXISTS_ERROR);
        }

        try {

            List<UsuallyDriver> drivers = usuallyDriverService.getUsuallyDriver(phone, longitude,
                latitude);

            List<Map<String, Object>> mapList = new ArrayList<Map<String, Object>>();
            if (org.apache.commons.collections.CollectionUtils.isNotEmpty(drivers)) {
                Setting setting = settingUtils.get();
                for (UsuallyDriver usuallyDriver : drivers) {
                    Driver driver = usuallyDriver.getDriver();
                    Map<String, Object> map = new HashMap<String, Object>();
                    map.put("driverId", driver.getId());
                    map.put("driverName", driver.getName());
                    map.put("driverUserName", driver.getUsername());
                    map.put("driverHead",
                        setting.getWebUrl() + "/upload/driver/" + driver.getPhoto());
                    map.put("driverStar", driver.getStarLevel());
                    map.put("driverTimes", driver.getDriveTimes());
                    map.put("driverJialing", driver.getjialing());
                    map.put("driverDistance", driver.getDistanceStr());
                    map.put("driverMeter", driver.getDistance() * 1000);
                    if (driver.getStatus().equals(Driver.DRIVER_ONLINE)) {
                        map.put("driverStatus", 0);
                    } else {
                        map.put("driverStatus", 1);
                    }
                    map.put("driverLng", driver.getLongitude());
                    map.put("driverLat", driver.getLatitude());
                    mapList.add(map);
                }
            }

            ResultTransport instance = ResultTransport.getErrorBy(ErrorConstant.SUCCESS);
            instance.setData(mapList);

            return instance;

        } catch (Exception e) {
            logger.error("api v3 member getUsuallyDriver error: {}", e);
            return ResultTransport.getErrorBy(ErrorConstant.SERVER_ERROR);
        }

    }

    /**
     * 获取订单信息
     */
    @RequestMapping(value = "orderInfo", method = RequestMethod.POST)
    public @ResponseBody
    ResultTransport orderInfo(Long orderId, String appKey, String token,
        String timestamp) {

        logger.debug("recv orderId:{},appKey:{},token:{},timestamp:{}", orderId, appKey, token,
            timestamp);

        if (null == orderId || SecurityUtils.isBlank(appKey, token, timestamp)) {
            return ResultTransport.getErrorBy(ErrorConstant.PARAM_ERROR);
        }

        // if(!StringUtils.isNumeric(timestamp) ||
        // !SecurityUtils.checkTimestamp(Long.parseLong(timestamp))) {
        // return ResultTransport.getErrorBy(ErrorConstant.TIMESTAMP_ERROR);
        // }

        List<String> params = new LinkedList<String>();
        params.add(String.valueOf(orderId));
        params.add(timestamp);
        params.add(appKey);

        if (!SecurityUtils.checkToken(params, token)) {
            return ResultTransport.getErrorBy(ErrorConstant.TOKEN_ERROR);
        }

        Order order = orderService.findOne(orderId);
        if (null == order) {
            return ResultTransport.getErrorBy(ErrorConstant.ORDER_NOT_EXISTS_ERROR);
        }
        order.setOrderStatuss(orderStatusService.findByOrder(order.getId()));

        try {

            Setting setting = settingUtils.get();

            Map<String, Object> map = new HashMap<String, Object>();
            map.put("orderId", order.getId());
            map.put("orderNumber", order.getOrderNumber());
            map.put("orderBookTime", order.getServerTime());
            map.put("orderBookAddress", order.getFromPlace());
            map.put("orderBookLat", order.getClientLatitude());
            map.put("orderBookLng", order.getClientLongitude());
            map.put("orderStatus", order.getStatus());
            map.put("orderCarType", order.getOrderCarType());
            if (null != order.getDriverId()) {
                Driver driver = driverService.findOne(order.getDriverId());
                if (null != driver) {
                    map.put("orderDriverId", driver.getId());
                    map.put("orderDriverAccount", driver.getUsername());
                    map.put("orderDriverName", driver.getName());
                    map.put("orderDriverHead",
                        setting.getWebUrl() + "/upload/driver/" + driver.getPhoto());
                    if (!setting.isAllowCallDriver()) {
                        Company company = companyService.findOne(order.getCompanyId());
                        map.put("orderDriverPhone", company.getTelephone());
                    } else {
                        map.put("orderDriverPhone", driver.getPhone());
                    }
                    map.put("orderDriverLat", driver.getLatitude());
                    map.put("orderDriverLng", driver.getLongitude());
                    map.put("orderDriverPaidan", order.getAcceptTime());
                    map.put("orderDriverAccept", order.getChufaTime());
                    map.put("orderDriverArrived", order.getDaokehuTime());
                    map.put("orderDriverStar", driver.getStarLevel());
                    map.put("orderDriverTimes", driver.getDriveTimes());
                    map.put("orderDriverJialing", driver.getjialing());
                }
            }

            ResultTransport instance = ResultTransport.getErrorBy(ErrorConstant.SUCCESS);
            instance.setData(map);

            return instance;

        } catch (Exception e) {
            logger.error("api v3 member orderInfo error: {}", e);
            return ResultTransport.getErrorBy(ErrorConstant.SERVER_ERROR);
        }

    }

    /**
     * 客户销单
     *
     * @return
     */
    @RequestMapping(value = "customerCancel", method = RequestMethod.POST)
    public @ResponseBody
    ResultTransport customerCancel(Long orderId, String content, String appKey,
        String token, String timestamp) {

        logger.debug("recv orderId:{},content{},appKey:{},token:{},timestamp:{}", orderId, content,
            appKey, token, timestamp);

        if (null == orderId || StringUtils.isBlank(content)
            || SecurityUtils.isBlank(appKey, token, timestamp)) {
            return ResultTransport.getErrorBy(ErrorConstant.PARAM_ERROR);
        }

        // if(!StringUtils.isNumeric(timestamp) ||
        // !SecurityUtils.checkTimestamp(Long.parseLong(timestamp))) {
        // return ResultTransport.getErrorBy(ErrorConstant.TIMESTAMP_ERROR);
        // }

        List<String> params = new LinkedList<String>();
        params.add(String.valueOf(orderId));
        params.add(String.valueOf(content));
        params.add(timestamp);
        params.add(appKey);

        if (!SecurityUtils.checkToken(params, token)) {
            return ResultTransport.getErrorBy(ErrorConstant.TOKEN_ERROR);
        }

        Order order = orderService.findOne(orderId);
        if (null == order) {
            return ResultTransport.getErrorBy(ErrorConstant.ORDER_NOT_EXISTS_ERROR);
        }

        if (!order.getStatus().equals(Order.ORDER_STATUS_NEW)
            && !order.getStatus().equals(Order.ORDER_STATUS_YIPAIDAN)
            && !order.getStatus().equals(Order.ORDER_STATUS_BUSY)) {
            return ResultTransport.getErrorBy(ErrorConstant.ORDER_STATUS_ERROR);
        }

        if (order.getStatus().equals(Order.ORDER_STATUS_BUSY)) {
            List<OrderStatus> orderStatuss = orderStatusService.findByOrder(order.getId());
            if (!CollectionUtils.isEmpty(orderStatuss)) {
                Collections.sort(orderStatuss, new Comparator<OrderStatus>() {
                    public int compare(OrderStatus arg0, OrderStatus arg1) {
                        return arg1.getId().compareTo(arg0.getId());
                    }
                });
            }
            if (orderStatuss.get(0).getStatusType().equals(OrderStatus.StatusType.daijia2)) {
                return ResultTransport.getErrorBy(ErrorConstant.ORDER_STATUS_ERROR);
            }
            // order.setOrderStatuss(orderStatuss);
            // if(null!=order.getDaokehuTime()){
            // return ResultTransport.getErrorBy(ErrorConstant.ORDER_STATUS_ERROR);
            // }
        }

        try {
            orderService.customerCancel(order, content);

            ResultTransport instance = ResultTransport.getErrorBy(ErrorConstant.SUCCESS);

            return instance;

        } catch (Exception e) {
            logger.error("api v3 member customerCancel error: {}", e);
            return ResultTransport.getErrorBy(ErrorConstant.SERVER_ERROR);
        }

    }

    /**
     * 乘客获取app设置
     * @record zhyu
     * @return
     */
    @RequestMapping(value = "getAppSetting", method = RequestMethod.POST)
    public @ResponseBody
    ResultTransport getAppSetting(
        @RequestParam(required = false, value = "acKey") String acKey,
        @RequestParam(required = false, value = "companyId") Long companyId,
        @RequestParam(required = false, value = "longitude") Double longitude,
        @RequestParam(required = false, value = "latitude") Double latitude) {
        try {
            Setting setting = settingUtils.get();

            Map<String, Object> mapData = new HashMap<String, Object>();

            Map<String, Object> shareMap = new HashMap<String, Object>();
            String title, content, image, shareURL;
            Company companyByAppKey = null;
            if (StringUtils.isNotBlank(acKey)) {
                Company company = companyService.findByAppKey(acKey);
                if (company != null) {
                    companyByAppKey = company;
                }
            }

            if (companyByAppKey == null && longitude != null && latitude != null) {

                String city = "";
                int i = 0;
                while (i < 5) {
                    city = HttpClientUtil.getCityByLngAndLat(longitude, latitude);
                    if (StringUtils.isNotBlank(city)) {
                        break;
                    }
                    i++;
                }
                List<Company> companyList = null;
                if (StringUtils.isNotBlank(city)) {
                    companyList = companyService.findByAreaCityName(city);
                }
                if (!CollectionUtils.isEmpty(companyList)) {
                    if (companyId != null && companyId != 0) {
                        for (Company c : companyList) {
                            if (c.getId().equals(companyId)) {
                                companyByAppKey = c;
                                break;
                            }
                        }
                    }

                    List<Company> notMainCompanys = new ArrayList<Company>();// 子公司
                    Company cityMainCompany = null;

                    if (null == companyByAppKey) {
                        for (Company c : companyList) {
                            if (!c.isCompanyType()) {
                                if (StringUtils.isBlank(c.getAppKey())) {
                                    notMainCompanys.add(c);
                                }
                            } else {
                                cityMainCompany = c;
                            }
                        }
                        if (!CollectionUtils.isEmpty(notMainCompanys)) {
                            companyByAppKey = notMainCompanys
                                .get(new Random().nextInt(notMainCompanys.size()));
                        }
                    }

                    if (null == companyByAppKey) {
                        if (null != cityMainCompany) {
                            companyByAppKey = cityMainCompany;
                        }
                    }

                }
            }
            if (companyByAppKey == null) {
                companyByAppKey = companyService.getMain();
            }
            title = companyByAppKey.getShareTitle();
            content = companyByAppKey.getShareContent();
            image = setting.getWebUrl() + "/" + companyByAppKey.getShareImage();
            shareURL = companyByAppKey.getShareURL();

            shareMap.put("title", title); // 分享的标题
            shareMap.put("content", content); // 分享的内容
            shareMap.put("image", image); // 分享的图片
            shareMap.put("shareURL", shareURL); // 分享的链接

            mapData.put("share", shareMap);

            Map<String, Object> aboutMap = new HashMap<String, Object>();
            aboutMap.put("web", companyByAppKey.getCompanyWebURL()); // 公司网址
            aboutMap.put("tel", companyByAppKey.getTelephone()); // 公司联系电话
            aboutMap.put("image", setting.getWebUrl() + "/" + companyByAppKey.getLogo());// 公司logo
            mapData.put("about", aboutMap);

            List<Advert> advert = advertService.findAll();
            List<Map<String, Object>> advertListMap = new ArrayList<Map<String, Object>>();
            for (Advert a : advert) {
                Map<String, Object> advertMap = new HashMap<String, Object>();
                advertMap.put("adName", a.getAdName());
                advertMap.put("address", a.getAddress());
                advertMap.put("picture", setting.getWebUrl() + "/upload/advert/" + a.getPicture());
                advertListMap.add(advertMap);
            }
            mapData.put("adverList", advertListMap);

            List<Company> companyList = new ArrayList<Company>();

            Company appointCompany = null;
            if (StringUtils.isNotBlank(acKey)) {
                appointCompany = companyService.findByAppKey(acKey);
            }

            if (null != appointCompany) {
                companyList.add(appointCompany);
            } else {
                companyList = companyService.findAll();
            }

            List<Map<String, Object>> telsMapList = new ArrayList<Map<String, Object>>();
            for (Company company : companyList) {
                Map<String, Object> telsMap = new HashMap<String, Object>();
                telsMap.put("companyId", company.getId());
                telsMap.put("city", company.getCityName());
                telsMap.put("tel", company.getTelephone());
                telsMap.put("emergencyPhone", company.getEmergencyPhone());
                if (company.isCompanyType()) {
                    telsMap.put("isMain", "1");
                } else {
                    telsMap.put("isMain", "0");
                }
                telsMapList.add(telsMap);
            }
            mapData.put("tels", telsMapList);

            // 租车车辆类型
            ServiceSetting serviceSetting = ServiceUtil.checkOpen();
            if (serviceSetting.isZuche()) {
                List<com.ybkj.daijia.server.model.CarType> list = carTypeService.findAll();
                if (!CollectionUtils.isEmpty(list)) {
                    List<Map<String, Object>> carTypeMapList = new ArrayList<Map<String, Object>>();
                    for (com.ybkj.daijia.server.model.CarType carType : list) {
                        Map<String, Object> carTypeMap = new HashMap<String, Object>();
                        carTypeMap.put("name", carType.getName());
                        carTypeMap.put("id", carType.getId());
                        carTypeMapList.add(carTypeMap);
                    }
                    mapData.put("zucheCarTypes", carTypeMapList);
                }
                // 租车品牌
                List<Brand> brands = brandService.listWithName();
                if (!CollectionUtils.isEmpty(brands)) {
                    List<Map<String, Object>> brandsMapList = new ArrayList<Map<String, Object>>();
                    for (Brand brand : brands) {
                        Map<String, Object> brandsMap = new HashMap<String, Object>();
                        brandsMap.put("name", brand.getName());
                        brandsMap.put("id", brand.getId());
                        brandsMapList.add(brandsMap);
                    }
                    mapData.put("brands", brandsMapList);
                }
            }

            // 车辆类型(专车的车辆类型)
            try {
                List<CarType> carTypes = zhuancheService.queryCarTypes(companyByAppKey.getId());
                if (!CollectionUtils.isEmpty(carTypes)) {
                    List<Map<String, Object>> carTypesMapList = new ArrayList<Map<String, Object>>();
                    for (CarType carType : carTypes) {
                        Map<String, Object> carTypesMap = new HashMap<String, Object>();
                        carTypesMap.put("name", carType.getTypeName());
                        carTypesMap.put("carTypeId", carType.getId());
                        carTypesMap.put("areaId", carType.getAreaId());
                        carTypesMap.put("picture", carType.getPicture());
                        carTypesMap.put("carTypeCompanyId", carType.getCompanyId());
                        carTypesMap.put("carTypeCompanyName", carType.getCompanyName());
                        carTypesMapList.add(carTypesMap);
                    }
                    mapData.put("carTypes", carTypesMapList);
                }
            } catch (Exception e) {
                e.printStackTrace();
            }

            // 配置
            mapData.put("errandPrePay", setting.isPaotuiPrePay());// 跑腿预付费
            mapData.put("prePay", setting.isZhuanchePrePay());// 专车预付费

            // 开启的服务
            Properties prop = PropertiesLoaderUtils.loadAllProperties("config.properties");

            String daijia = prop.getProperty("function.daijia.open");
            String zhuanche = prop.getProperty("function.zhuanche.open");
            String gasstation = prop.getProperty("function.gasstation.open");
            String zuche = prop.getProperty("function.zuche.open");
            String paotui = prop.getProperty("function.paotui.open");
            String partner = prop.getProperty("function.partner.open");
            String freight = prop.getProperty("function.freight.open");
            String zhuanxian = prop.getProperty("function.zhuanxian.open");
            Map<String, Object> serviceMap = new HashMap<String, Object>();
            serviceMap.put("daijia", Boolean.valueOf(daijia));
            serviceMap.put("zhuanche", Boolean.valueOf(zhuanche));
            serviceMap.put("zuche", Boolean.valueOf(zuche));
            serviceMap.put("paotui", Boolean.valueOf(paotui));
            serviceMap.put("partner", Boolean.valueOf(partner));
            serviceMap.put("freight", Boolean.valueOf(freight));
            serviceMap.put("zhuanxian", Boolean.valueOf(zhuanxian));
            serviceMap.put("gasstation", Boolean.valueOf(gasstation));
            mapData.put("serviceType", serviceMap);
            // 专线预约时时间限定
            mapData.put("bookTimeZhuanxian", setting.getBookTimeZhuanxian());
            mapData.put("bookTimeZhuan", setting.getBookTimeZhuan());
            mapData.put("customTitle", companyByAppKey.getCustomTitle());
            // 是否开启双因子验证
            mapData.put("doubleFactor", setting.isDoubleFactor());
            String customUrl = "";
            if (setting.getWebUrl().endsWith("/")) {
                customUrl = setting.getWebUrl();
            } else {
                customUrl = setting.getWebUrl() + "/";
            }
            mapData.put("customContent", customUrl + "member/api/rest/v3/custom?companyId="
                + companyByAppKey.getId());

            // 在线支付开启情况
            Map<String, Object> onlinePayMap = new HashMap<String, Object>();
            boolean aliPay = true;
            boolean weixinPay = true;
            boolean unionPay = true;
            boolean bestPay = true;
            if (StringUtils.isBlank(setting.getAlipayPartnerID())
                || StringUtils.isBlank(setting.getAlipaySellerID())
                || StringUtils.isBlank(setting.getAlipayPartnerPrivKey())) {
                aliPay = false;
            }
            if (StringUtils.isBlank(setting.getWxAppID())
                || StringUtils.isBlank(setting.getWxAppSecret())
                || StringUtils.isBlank(setting.getWxPartnerID())
                || StringUtils.isBlank(setting.getWxPartnerKey())) {
                weixinPay = false;
            }
            if (StringUtils.isBlank(setting.getMerId()) || StringUtils
                .isBlank(setting.getAcpProdEnc())
                || StringUtils.isBlank(setting.getAcpProdMiddle())
                || StringUtils.isBlank(setting.getAcpProdRoot())
                || StringUtils.isBlank(setting.getAcpsdkSignCertPath())
                || StringUtils.isBlank(setting.getAcpsdkSignCertPwd())) {
                unionPay = false;
            }
            if (StringUtils.isBlank(setting.getMerchantId()) || StringUtils
                .isBlank(setting.getMerKey())
                || StringUtils.isBlank(setting.getRiskcontrolinfo())) {
                bestPay = false;
            }
            onlinePayMap.put("aliPay", aliPay);
            onlinePayMap.put("weixinPay", weixinPay);
            onlinePayMap.put("unionPay", unionPay);
            onlinePayMap.put("bestPay", bestPay);
            mapData.put("onlinePay", onlinePayMap);

            ResultTransport instance = ResultTransport.getErrorBy(ErrorConstant.SUCCESS);
            instance.setData(mapData);

            return instance;

        } catch (Exception e) {
            e.printStackTrace();
            return ResultTransport.getErrorBy(ErrorConstant.SERVER_ERROR);
        }

    }

    /**
     * 服务协议(优先选子公司)
     *
     * @param companyId 客户所在公司id
     */
    @RequestMapping("agreement")
    public String agreement(@RequestParam(required = false, value = "acKey") String acKey,
        @RequestParam(required = false, value = "longitude") Double longitude,
        @RequestParam(required = false, value = "companyId") Long companyId,
        @RequestParam(required = false, value = "latitude") Double latitude, Model model) {
        String agreement = null;
        if (StringUtils.isNotBlank(acKey)) {
            Company company = companyService.findByAppKey(acKey);
            if (StringUtils.isNotBlank(company.getAgreement())) {
                agreement = company.getAgreement();
            } else {
                agreement = companyService.getMain().getAgreement();
            }
        } else if (longitude != null && latitude != null) {
            String city = HttpClientUtil.getCityByLngAndLat(longitude, latitude);
            List<Company> companyList = null;
            if (StringUtils.isNotBlank(city)) {
                companyList = companyService.findByAreaCityName(city);
            }
            if (!CollectionUtils.isEmpty(companyList)) {

                for (Company c : companyList) {
                    if (c.getId().equals(companyId)) {
                        agreement = c.getAgreement();
                        break;
                    }
                }
                if (StringUtils.isBlank(agreement)) {
                    List<Company> notMainCompanys = new ArrayList<Company>();
                    for (Company c : companyList) {
                        if (!c.isCompanyType()) {
                            if (StringUtils.isBlank(c.getAppKey())) {
                                notMainCompanys.add(c);
                            }
                        }
                    }
                    if (!CollectionUtils.isEmpty(notMainCompanys)) {
                        agreement = notMainCompanys
                            .get(new Random().nextInt(notMainCompanys.size()))
                            .getAgreement();
                    }
                }
            }
        }
        if (StringUtils.isBlank(agreement)) {
            agreement = companyService.getMain().getAgreement();
        }
        model.addAttribute("agreement", HtmlHelper.htmlscripttext(agreement));

        return "member/agreement";

    }

    /**
     * 服务协议(优先选子公司)(过APP评测)
     *
     * @param companyId 客户所在公司id
     */
    @RequestMapping("agreement2")
    public @ResponseBody
    ResultTransport agreement2(
        @RequestParam(required = false, value = "acKey") String acKey,
        @RequestParam(required = false, value = "longitude") Double longitude,
        @RequestParam(required = false, value = "companyId") Long companyId,
        @RequestParam(required = false, value = "latitude") Double latitude,
        HttpServletRequest request) {
        String agreement = null;
        if (StringUtils.isNotBlank(acKey)) {
            Company company = companyService.findByAppKey(acKey);
            if (StringUtils.isNotBlank(company.getAgreement())) {
                agreement = company.getAgreement();
            } else {
                agreement = companyService.getMain().getAgreement();
            }
        } else if (longitude != null && latitude != null) {
            String city = HttpClientUtil.getCityByLngAndLat(longitude, latitude);
            List<Company> companyList = null;
            if (StringUtils.isNotBlank(city)) {
                companyList = companyService.findByAreaCityName(city);
            }
            if (!CollectionUtils.isEmpty(companyList)) {

                for (Company c : companyList) {
                    if (c.getId().equals(companyId)) {
                        agreement = c.getAgreement();
                        break;
                    }
                }
                if (StringUtils.isBlank(agreement)) {
                    List<Company> notMainCompanys = new ArrayList<Company>();
                    for (Company c : companyList) {
                        if (!c.isCompanyType()) {
                            if (StringUtils.isBlank(c.getAppKey())) {
                                notMainCompanys.add(c);
                            }
                        }
                    }
                    if (!CollectionUtils.isEmpty(notMainCompanys)) {
                        agreement = notMainCompanys
                            .get(new Random().nextInt(notMainCompanys.size()))
                            .getAgreement();
                    }
                }
            }
        }
        if (StringUtils.isBlank(agreement)) {
            agreement = companyService.getMain().getAgreement();
        }

        try {
            String path = String.format("%s/WEB-INF/views/member/", Config.getWebapp());

            Configuration cfg = new Configuration();

            cfg.setTemplateLoader(new FileTemplateLoader(new File(path)));
            cfg.setDefaultEncoding("UTF-8");

            Template template = cfg.getTemplate("agreement2.ftl");

            Map<String, Object> root = new HashMap<String, Object>();
            root.put("ctx", request.getContextPath());
            root.put("agreement", HtmlHelper.htmlscripttext(agreement));

            StringWriter writer = new StringWriter();
            template.process(root, writer);

            ResultTransport instance = ResultTransport.getErrorBy(ErrorConstant.SUCCESS);
            Map<String, String> datamap = new HashMap<String, String>();
            datamap.put("content", HtmlHelper.replaceBlank(writer.toString()));
            instance.setData(datamap);
            return instance;

        } catch (IOException e) {
            e.printStackTrace();
            return ResultTransport.getErrorBy(ErrorConstant.SERVER_ERROR);
        } catch (TemplateException e) {
            e.printStackTrace();
            return ResultTransport.getErrorBy(ErrorConstant.SERVER_ERROR);
        }

    }

    /**
     * 查询用户协议(纯文本).
     */
    @RequestMapping(value = "agreementText", method = {RequestMethod.GET})
    public @ResponseBody
    String agreementText(
        @RequestParam(required = false, value = "acKey") String acKey,
        @RequestParam(required = false, value = "longitude") Double longitude,
        @RequestParam(required = false, value = "companyId") Long companyId,
        @RequestParam(required = false, value = "latitude") Double latitude) {
        String agreement = null;
        if (StringUtils.isNotBlank(acKey)) {
            Company company = companyService.findByAppKey(acKey);
            if (StringUtils.isNotBlank(company.getAgreement())) {
                agreement = company.getAgreement();
            } else {
                agreement = companyService.getMain().getAgreement();
            }
        } else if (longitude != null && latitude != null) {
            String city = HttpClientUtil.getCityByLngAndLat(longitude, latitude);
            List<Company> companyList = null;
            if (StringUtils.isNotBlank(city)) {
                companyList = companyService.findByAreaCityName(city);
            }
            if (!CollectionUtils.isEmpty(companyList)) {

                for (Company c : companyList) {
                    if (c.getId().equals(companyId)) {
                        agreement = c.getAgreement();
                        break;
                    }
                }
                if (StringUtils.isBlank(agreement)) {
                    List<Company> notMainCompanys = new ArrayList<Company>();
                    for (Company c : companyList) {
                        if (!c.isCompanyType()) {
                            if (StringUtils.isBlank(c.getAppKey())) {
                                notMainCompanys.add(c);
                            }
                        }
                    }
                    if (!CollectionUtils.isEmpty(notMainCompanys)) {
                        agreement = notMainCompanys
                            .get(new Random().nextInt(notMainCompanys.size()))
                            .getAgreement();
                    }
                }
            }
        }
        if (StringUtils.isBlank(agreement)) {
            agreement = companyService.getMain().getAgreement();
        }

        agreement = HtmlHelper.html2Text(agreement);

        return agreement;
    }

    @RequestMapping(value = "custom", method = RequestMethod.GET)
    public String custom(Long companyId, Model model) {
        Company company = companyService.findOne(companyId);
        String customTitle = "";
        String customContent = "";
        customTitle = company.getCustomTitle();
        customContent = company.getCustomContent();
        model.addAttribute("customTitle", customTitle);
        model.addAttribute("customContent", customContent);

        return "company/custom";
    }

    /**
     * 分享成功
     *
     * @param phone     手机号
     * @param appKey
     * @param token     token令牌
     * @param timestamp 时间戳
     * @return
     */
    @RequestMapping(value = "shareSuccess", method = RequestMethod.POST)
    public synchronized @ResponseBody
    ResultTransport shareSuccess(String phone, String deviceType,
        SharePlatform sharePlatform, String appKey, String token, String timestamp) {

        logger.debug("recv phone:{},deviceType:{},sharePlatform:{},appKey:{},token:{},timestamp:{}",
            phone, deviceType, sharePlatform, appKey, token, timestamp);

        if (StringUtils.isBlank(phone) || StringUtils.isBlank(deviceType) || null == sharePlatform
            || SecurityUtils.isBlank(appKey, token, timestamp)) {
            return ResultTransport.getErrorBy(ErrorConstant.PARAM_ERROR);
        }

        // if(!StringUtils.isNumeric(timestamp) ||
        // !SecurityUtils.checkTimestamp(Long.parseLong(timestamp))) {
        // return ResultTransport.getErrorBy(ErrorConstant.TIMESTAMP_ERROR);
        // }

        List<String> params = new LinkedList<String>();
        params.add(phone);
        params.add(deviceType);
        params.add(sharePlatform.toString());
        params.add(timestamp);
        params.add(appKey);

        if (!SecurityUtils.checkToken(params, token)) {
            return ResultTransport.getErrorBy(ErrorConstant.TOKEN_ERROR);
        }

        Passenger passenger = memberService.findOnePassengerByPhone(phone);

        if (null == passenger) {
            return ResultTransport.getErrorBy(ErrorConstant.MEMBER_NOT_EXISTS_ERROR);
        }

        try {

            ShareRecord shareRecord = new ShareRecord();
            shareRecord.setDeviceType(deviceType);
            shareRecord.setMemberId(passenger.getId());
            shareRecord.setPhone(phone);
            shareRecord.setSharePlatform(sharePlatform);

            ReactorVo rVo = new ReactorVo();
            rVo.setPassenger(passenger);
            rVo.setActivityEvent(ActivityEvent.shareSuccess);
            rVo.setShareRecord(shareRecord);
            ActivityCheckEvent activityCheckEvent = new ActivityCheckEvent(rVo);
            applicationEventMulticaster.multicastEvent(activityCheckEvent);

            ResultTransport instance = ResultTransport.getErrorBy(ErrorConstant.SUCCESS);

            return instance;

        } catch (Exception e) {
            logger.error("api v3 member shareSuccess error: {}", e);
            return ResultTransport.getErrorBy(ErrorConstant.SERVER_ERROR);
        }

    }

    /**
     * 推荐人二维码
     */
    @RequestMapping("getQrCode/{id}")
    public String getQrCode(HttpServletRequest req, Model model, @PathVariable("id") Long id,
        String acKey) {

        String bathPath = getBasePath(req);

        Setting setting = settingUtils.get();

        String shareUrl = setting.getWebUrl();
        shareUrl += "/member/api/rest/v3/shareQrCode/" + id + "";

        Company company = null;
        String qrLogo = null;
        File logof = null;
        Passenger passenger = memberService.findOnePassenger(id);

        if (StringUtils.isNotBlank(acKey)) {
            company = companyService.findByAppKey(acKey);
            if (null != company) {
                shareUrl += "?cid=" + company.getId() + "";
            }
        }
        if (null == company && null != passenger) {
            company = companyService.findOne(passenger.getCompanyId());
        }
        if (null != company) {
            qrLogo = company.getLogo();
        }
        if (null != qrLogo) {
            logof = new File(bathPath, qrLogo);
        }

        String srcLogo = null;

        if (null != logof && logof.exists()) {
            srcLogo = logof.getAbsolutePath();
        }

        SimpleDateFormat monthFormat = new SimpleDateFormat("yyyyMM");
        Date now = new Date();
        String monthstr = monthFormat.format(now);
        String filestr = "qrcode/member/" + monthstr + "/" + now.getTime() + ".jpg";

        File f = new File(bathPath, filestr);
        if (!f.getParentFile().exists()) {
            f.getParentFile().mkdirs();
        }

        QRCodeUtil.encode(shareUrl, 500, 500, srcLogo, bathPath + "/" + filestr);

        model.addAttribute("path", filestr);

        return "memberrebate/getqrcode";

    }

    @RequestMapping("shareQrCode/{id}")
    public String shareQrCode(HttpServletRequest req, Model model, @PathVariable("id") Long id,
        Long cid) {

        Passenger passenger = memberService.findOnePassenger(id);
        model.addAttribute("passenger", passenger);
        Company company = null;
        if (null != cid) {
            company = companyService.findOne(cid);
        }
        if (null == company) {
            company = companyService.findOne(passenger.getCompanyId());
        }
        model.addAttribute("wxsetting", settingUtils.getWx());
        model.addAttribute("company", company);

        return "memberrebate/shareqrcode";

    }

    @RequestMapping("smsQrCode")
    public @ResponseBody
    Result<PhoneSmsRecord> smsQrCode(Long companyId, String phone,
        Long introducerId) {

        Result<PhoneSmsRecord> result = new Result<PhoneSmsRecord>();

        Passenger introducer = memberService.findOnePassenger(introducerId);
        Company company = null;
        if (null != companyId) {
            company = companyService.findOne(companyId);
        }
        if (null == company) {
            company = companyService.findOne(introducer.getCompanyId());
        }
        Company finalCompany = company;
        Company main = companyService.getMain();
        Setting setting = settingUtils.get();
        if (!main.getId().equals(company.getId()) && setting.isSmsMainCompany()) {
            finalCompany = main;
        }

        PhoneSmsRecord phoneSmsRecord = phoneSmsRecordService.findByPhone(phone);
        if (null != phoneSmsRecord) {
            long time = (System.currentTimeMillis() - phoneSmsRecord.getExpired().getTime()) / 1000;// 多少秒
            if (time < 120) {// 2分内禁止发送
                result.setErrorcode("0");
                result.setObject(120 - time);
                return result;
            } else if (time >= 120 && time < 30 * 60) {// 30分内发送旧的
                result.setErrorcode("1");
                int code = -99;
                try {
                    //String con = "尊敬的用户您好,验证码：" + phoneSmsRecord.getVcode();
                    SmsTemplet templet = smsService
                        .findByAlias(finalCompany.getId(), SmsType.customDriver);
//          if (templet == null) {
//            SmsTemplet smsTemplet = new SmsTemplet();
//            smsTemplet.setCompanyId(finalCompany.getId());
//            smsTemplet.setContent("{content}");
//            smsTemplet.setSmsType(SmsType.customMember);
//            smsService.insertSmsTemplate("活动信息", SmsTemplet.SMSTEMPLATE_TYPE_CODE, smsTemplet);
//          }
                    if (templet != null && StringUtils.isNotBlank(templet.getContent())) {
//            code = smsService.sendSms(phone, "customMember", "{\"content\":\"" + con + "\"}",
//                finalCompany.getId(), 2, finalCompany.getSignName());
                        //短信发送（改）
                        JSONObject smsParam = new JSONObject();
                        smsParam.put("code", phoneSmsRecord.getVcode());
                        code = smsService
                            .sendSms(phone, templet.getTemplateId(), smsParam.toJSONString(),
                                finalCompany.getId(), 2, finalCompany.getSignName());
                    }
                } catch (Exception e) {
                }
                logger.debug("验证码发送结果：" + code + "，验证码：" + phoneSmsRecord.getVcode());
                if (code == 0) {
                    result.setSuccess(true);
                    phoneSmsRecord.setExpired(new Date());
                    phoneSmsRecordService.update(phoneSmsRecord);
                }
                return result;
            } else {// 超过30分 发送新的
                result.setErrorcode("1");
                String newCode = String.valueOf(RandomString.randomNum(4));
                int code = -99;
                try {
                    String con = "尊敬的用户您好,验证码：" + newCode;
                    SmsTemplet templet = smsService
                        .findByAlias(finalCompany.getId(), SmsType.customDriver);
//          if (templet == null) {
//            SmsTemplet smsTemplet = new SmsTemplet();
//            smsTemplet.setCompanyId(finalCompany.getId());
//            smsTemplet.setContent("{content}");
//            smsTemplet.setSmsType(SmsType.customMember);
//            smsService.insertSmsTemplate("活动信息", SmsTemplet.SMSTEMPLATE_TYPE_CODE, smsTemplet);
//          }
                    if (templet != null && StringUtils.isNotBlank(templet.getContent())) {
//            code = smsService.sendSms(phone, "customMember", "{\"content\":\"" + con + "\"}",
//                finalCompany.getId(), 2, finalCompany.getSignName());
                        //短信发送（改）
                        JSONObject smsParam = new JSONObject();
                        smsParam.put("code", newCode);
                        code = smsService
                            .sendSms(phone, templet.getTemplateId(), smsParam.toJSONString(),
                                finalCompany.getId(), 2, finalCompany.getSignName());
                    }
                } catch (Exception e) {
                }
                logger.debug("验证码发送结果：" + code + "，验证码：" + newCode);
                if (code == 0) {
                    result.setSuccess(true);
                    phoneSmsRecord.setExpired(new Date());
                    phoneSmsRecord.setVcode(newCode);
                    phoneSmsRecordService.update(phoneSmsRecord);
                }
                return result;
            }
        } else {
            result.setErrorcode("1");
            String newCode = String.valueOf(RandomString.randomNum(4));
            int code = -99;
            try {
                String con = "尊敬的用户您好,验证码：" + newCode;
                SmsTemplet templet = smsService
                    .findByAlias(finalCompany.getId(), SmsType.customDriver);
//        if (templet == null) {
//          SmsTemplet smsTemplet = new SmsTemplet();
//          smsTemplet.setCompanyId(finalCompany.getId());
//          smsTemplet.setContent("{content}");
//          smsTemplet.setSmsType(SmsTemplet.SmsType.customMember);
//          smsService.insertSmsTemplate("活动信息", SmsTemplet.SMSTEMPLATE_TYPE_CODE, smsTemplet);
//        }
                if (templet != null && StringUtils.isNotBlank(templet.getContent())) {
//          code = smsService.sendSms(phone, "customMember", "{\"content\":\"" + con + "\"}",
//              finalCompany.getId(), 2, finalCompany.getSignName());
                    //短信发送（改）
                    JSONObject smsParam = new JSONObject();
                    smsParam.put("code", newCode);
                    code = smsService
                        .sendSms(phone, templet.getTemplateId(), smsParam.toJSONString(),
                            finalCompany.getId(), 2, finalCompany.getSignName());
                }
            } catch (Exception e) {
            }
            logger.debug("验证码发送结果：" + code + "，验证码：" + newCode);
            if (code == 0) {
                result.setSuccess(true);
                phoneSmsRecord = new PhoneSmsRecord();
                phoneSmsRecord.setCompanyId(finalCompany.getId());
                phoneSmsRecord.setExpired(new Date());
                phoneSmsRecord.setPhone(phone);
                phoneSmsRecord.setVcode(newCode);
                phoneSmsRecordService.save(phoneSmsRecord);
            }

            return result;
        }

    }

    @RequestMapping(value = "downloadShareQrCode", method = RequestMethod.POST)
    public @ResponseBody
    Result<MemberRebate> downloadShareQrCode(String phone, String code, Long id) {

        logger.debug("recv phone:{},id:{}", phone, id);

        Result<MemberRebate> vo = new Result<MemberRebate>();
        vo.setSuccess(false);

        if (StringUtils.isBlank(phone) || StringUtils.isBlank(code) || null == id) {
            vo.setMessage("参数错误");
            return vo;
        }

        PhoneSmsRecord phoneSmsRecord = phoneSmsRecordService.findByPhone(phone);
        if (null == phoneSmsRecord || !phoneSmsRecord.getVcode().equals(code)) {
            vo.setMessage("验证码错误");
            return vo;
        }

        Passenger introducer = memberService.findOnePassenger(id);
        Passenger passenger = memberService.findOnePassengerByPhone(phone);

        boolean firstIntroducer = false;// 第一次

        if (null == passenger) {
            passenger = new Passenger();
            passenger.setPhone(phone);
            passenger.setType(Passenger.TYPE_PASSENGER);
            passenger.setChannel_name(Passenger.PASSENGER_CHANNEL_INVITE);
            passenger.setAllowOverdraw(Boolean.FALSE);
            if (null != introducer) {
                Company company = companyService.findOne(introducer.getCompanyId());
                passenger.setCompanyId(company.getId());
                passenger.setCompanyName(company.getAbbreviation());
                passenger.setIntroducer(introducer.getPhone());
                passenger.setIntroduceType(0);

                firstIntroducer = true;
            } else {
                Company company = companyService.getMain();
                passenger.setCompanyId(company.getId());
                passenger.setCompanyName(company.getAbbreviation());
            }
            Result<Passenger> result = memberService.createPersonal(passenger);

            if (result.isSuccess()) {
                // 新注册活动
                ReactorVo rVo = new ReactorVo();
                rVo.setPassenger(result.getResult());
                rVo.setActivityEvent(ActivityEvent.newRegister);
                ActivityCheckEvent activityCheckEvent = new ActivityCheckEvent(rVo);
                applicationEventMulticaster.multicastEvent(activityCheckEvent);

                if (firstIntroducer) {
                    MemberRebateEvent memberRebateEvent = new MemberRebateEvent(result.getResult(),
                        null,
                        null, 0);
                    applicationEventMulticaster.multicastEvent(memberRebateEvent);

                    ReactorVo rVo2 = new ReactorVo();
                    rVo2.setPassenger(introducer);
                    rVo2.setActivityEvent(ActivityEvent.invite);
                    ActivityCheckEvent activityCheckEvent2 = new ActivityCheckEvent(rVo2);
                    applicationEventMulticaster.multicastEvent(activityCheckEvent2);
                }
            } else {
                vo.setMessage(result.getMessage());
                return vo;
            }

        }

        phoneSmsRecordService.deleteByPhone(phone);

        Map<String, Object> urlMap = new HashMap<String, Object>();
        AppVersion androidcustomer = appVersionService
            .findByAppVersionType(AppVersion.AppVersionType.androidcustomer);
        AppVersion ioscustomer = appVersionService
            .findByAppVersionType(AppVersion.AppVersionType.ioscustomer);
        urlMap.put("androidUrl", androidcustomer.getDownloadurl());
        urlMap.put("iosUrl", ioscustomer.getDownloadurl());

        vo.setMap(urlMap);
        vo.setSuccess(true);

        return vo;

    }

    @RequestMapping("appXiazai")
    public String appXiazai(HttpServletRequest req, Model model) {

        return "memberrebate/appxiazai";

    }

    private String getBasePath(HttpServletRequest req) {

        try {
            return WebUtils.getRealPath(req.getSession().getServletContext(), "/");
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        }

        return StringUtils.EMPTY;
    }

    @RequestMapping(value = "queryMemberAlreadyMoney", method = RequestMethod.POST)
    public @ResponseBody
    ResultTransport queryAlreadyMoney(String phone, String appKey, String token,
        String timestamp) {

        logger.debug("money phone:{},appKey:{},token:{},timestamp:{}", phone, appKey, token,
            timestamp);

        if (StringUtils.isBlank(phone) || SecurityUtils.isBlank(appKey, token, timestamp)) {
            return ResultTransport.getErrorBy(ErrorConstant.PARAM_ERROR);
        }

        List<String> params = new LinkedList<String>();
        params.add(String.valueOf(phone));
        params.add(timestamp);
        params.add(appKey);
        if (!SecurityUtils.checkToken(params, token)) {
            return ResultTransport.getErrorBy(ErrorConstant.TOKEN_ERROR);
        }

        Passenger passenger = memberService.findOnePassengerByPhone(phone);
        if (null == passenger) {
            return ResultTransport.getErrorBy(ErrorConstant.MEMBER_NOT_EXISTS_ERROR);
        }

        ResultTransport instance = ResultTransport.getErrorBy(ErrorConstant.SUCCESS);
        instance.setData(passenger.getReceiptMoney());

        return instance;
    }

    @RequestMapping(value = "createReceipt", method = RequestMethod.POST)
    public @ResponseBody
    ResultTransport createReceipt(String phone, String appKey, String token,
        String timestamp, BigDecimal money, String type, String memo) {

        logger.debug(" phone:{},appKey:{},token:{},timestamp:{},money:{},type:{}", phone, appKey,
            token, timestamp, money, type);

        if (StringUtils.isBlank(phone) || null == money || StringUtils.isBlank(type)
            || SecurityUtils.isBlank(appKey, token, timestamp)) {
            return ResultTransport.getErrorBy(ErrorConstant.PARAM_ERROR);
        }

        List<String> params = new LinkedList<String>();
        params.add(String.valueOf(phone));
        params.add(String.valueOf(money));
        params.add(String.valueOf(type));

        params.add(timestamp);
        params.add(appKey);

        if (!SecurityUtils.checkToken(params, token)) {
            return ResultTransport.getErrorBy(ErrorConstant.TOKEN_ERROR);
        }

        Passenger passenger = memberService.findOnePassengerByPhone(phone);
        if (null == passenger) {
            return ResultTransport.getErrorBy(ErrorConstant.MEMBER_NOT_EXISTS_ERROR);
        }

        if (money.doubleValue() <= 0 || money.doubleValue() > passenger.getReceiptMoney()
            .doubleValue()) {
            return ResultTransport.getErrorBy(ErrorConstant.RECEIPT_ERROR);
        }
        Receipt receipt = new Receipt();

        receipt.setMemberId(passenger.getId());
        receipt.setMoney(money);
        receipt.setMemberName(passenger.getName());
        receipt.setMemberPhone(phone);
        receipt.setStatus(0);
        receipt.setType(type);

        if (StringUtils.isNotBlank(memo)) {
            receipt.setMemo(memo);
        }

        Result<Receipt> result = receiptService.createReceipt(passenger, receipt);

        if (result.isSuccess()) {
            ResultTransport instance = ResultTransport.getErrorBy(ErrorConstant.SUCCESS);
            return instance;
        } else {
            ResultTransport instance = ResultTransport
                .getErrorBy(new Error(-4, result.getMessage()));
            return instance;
        }

    }

    /**
     * V5微信公众号申请发票
     *
     * @param phone  电话
     * @param appKey 系统Key
     * @param money  钱
     * @param type   类型
     * @param memo   备注
     * @return
     */
    @ResponseBody
    @RequestMapping(value = "createReceiptV5", method = RequestMethod.POST)
    public ResultTransport createReceiptV5(String phone, String appKey, BigDecimal money,
        String type, String memo) {

        if (StringUtils.isBlank(phone) || null == money || StringUtils.isBlank(type)) {
            return ResultTransport.getErrorBy(ErrorConstant.PARAM_ERROR);
        }

        Passenger passenger = memberService.findOnePassengerByPhone(phone);
        if (null == passenger) {
            return ResultTransport.getErrorBy(ErrorConstant.MEMBER_NOT_EXISTS_ERROR);
        }

        if (money.doubleValue() <= 0 || money.doubleValue() > passenger.getReceiptMoney()
            .doubleValue()) {
            return ResultTransport.getErrorBy(ErrorConstant.RECEIPT_ERROR);
        }
        Receipt receipt = new Receipt();

        receipt.setMemberId(passenger.getId());
        receipt.setMoney(money);
        receipt.setMemberName(passenger.getName());
        receipt.setMemberPhone(phone);
        receipt.setStatus(0);
        receipt.setType(type);

        if (StringUtils.isNotBlank(memo)) {
            receipt.setMemo(memo);
        }
        Result<Receipt> result = receiptService.createReceipt(passenger, receipt);
        if (result.isSuccess()) {
            ResultTransport instance = ResultTransport.getErrorBy(ErrorConstant.SUCCESS);
            return instance;
        } else {
            ResultTransport instance = ResultTransport
                .getErrorBy(new Error(-4, result.getMessage()));
            return instance;
        }
    }

    @RequestMapping(value = "queryReceipt", method = RequestMethod.POST)
    public @ResponseBody
    ResultTransport queryReceipt(String phone, Integer page, Integer limit,
        String appKey, String token, String timestamp) {
        logger
            .debug(" phone:{},appKey:{},token:{},timestamp:{},page:{},limit:{}", phone, page, limit,
                appKey, token, timestamp);

        if (StringUtils.isBlank(phone) || SecurityUtils.isBlank(appKey, token, timestamp)) {
            return ResultTransport.getErrorBy(ErrorConstant.PARAM_ERROR);
        }

        List<String> params = new LinkedList<String>();
        params.add(String.valueOf(phone));
        params.add(String.valueOf(page));
        params.add(String.valueOf(limit));
        params.add(timestamp);
        params.add(appKey);

        if (!SecurityUtils.checkToken(params, token)) {
            return ResultTransport.getErrorBy(ErrorConstant.TOKEN_ERROR);
        }

        Passenger passenger = memberService.findOnePassengerByPhone(phone);
        if (null == passenger) {
            return ResultTransport.getErrorBy(ErrorConstant.MEMBER_NOT_EXISTS_ERROR);
        }

        try {

            Page<Receipt> pageReceipt = receiptService
                .queryByMemberId(passenger.getId(), page, limit);

            ResultTransport instance = ResultTransport.getErrorBy(ErrorConstant.SUCCESS);
            instance.setData(pageReceipt);

            return instance;

        } catch (Exception e) {
            logger.error("api v3 member pageNotice error: {}", e);
            return ResultTransport.getErrorBy(ErrorConstant.SERVER_ERROR);
        }

    }

    /**
     * v5微信获取客户发票申请记录
     *
     * @param phone  电话
     * @param page   页码
     * @param limit  条数
     * @param appKey 系统key
     * @return
     */
    @ResponseBody
    @RequestMapping(value = "queryReceiptV5", method = RequestMethod.POST)
    public ResultTransport queryReceiptV5(String phone, Integer page, Integer limit,
        String appKey) {

        if (StringUtils.isBlank(phone)) {
            return ResultTransport.getErrorBy(ErrorConstant.PARAM_ERROR);
        }

        Passenger passenger = memberService.findOnePassengerByPhone(phone);
        if (null == passenger) {
            return ResultTransport.getErrorBy(ErrorConstant.MEMBER_NOT_EXISTS_ERROR);
        }

        try {

            Page<Receipt> pageReceipt = receiptService
                .queryByMemberId(passenger.getId(), page, limit);
            ResultTransport instance = ResultTransport.getErrorBy(ErrorConstant.SUCCESS);
            instance.setData(pageReceipt);
            return instance;

        } catch (Exception e) {
            logger.error("api v3 member pageNotice error: {}", e);
            return ResultTransport.getErrorBy(ErrorConstant.SERVER_ERROR);
        }
    }

}
